package com.cke.yang.security.app.service.impl;

import com.cke.yang.common.domain.model.SecUserDetails;
import com.cke.yang.common.infra.utils.JwtUtils;
import com.cke.yang.security.api.dto.response.SecAuthLoginResponse;
import com.cke.yang.security.app.service.SecAuthService;
import com.cke.yang.security.domain.entity.SecUser;
import com.cke.yang.security.infra.mapper.SecUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.Map;

/**
 * 安全模块-认证服务
 *
 * @author yuyang
 */
@Slf4j
@Service
public class SecAuthServiceImpl implements SecAuthService {

    private final AuthenticationManager authenticationManager;

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private SecUserMapper secUserMapper;

    public SecAuthServiceImpl(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    private Authentication authenticate(String username, String password) {
        try {
            return authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(username, password)
            );
        } catch (AuthenticationException e) {
            throw new RuntimeException("用户名或密码错误", e);
        }
    }
    
    @Override
    public SecAuthLoginResponse login(String type, Map<String, String> bodyMap) {
        if (!StringUtils.hasLength(type) || CollectionUtils.isEmpty(bodyMap)) {
            throw new RuntimeException("参数缺失，登录失败");
        }

        Authentication authentication = this.loginByBasic(bodyMap);
        SecUserDetails userDetails = (SecUserDetails) authentication.getPrincipal();

        // 生成JWT Token，包含角色ID
        String accessToken = jwtUtils.generateAccessToken(
                userDetails.getUserId(),
                userDetails.getUsername(),
                userDetails.getCurrentRoleId()
        );
        String refreshToken = jwtUtils.generateRefreshToken(userDetails.getUserId(), userDetails.getUsername());

        // 更新最后登录时间
        updateLastLoginTimeByUserId(userDetails.getUserId());

        // 构建响应
        SecAuthLoginResponse response = new SecAuthLoginResponse();
        response.setAccessToken(accessToken);
        response.setRefreshToken(refreshToken);
        response.setExpires(System.currentTimeMillis() + jwtUtils.getAccessTokenExpiration());

        return response;
    }


    /**
     * 基础登录方式，基于 username+password形式
     */
    private Authentication loginByBasic(Map<String, String> bodyMap) {
        String username = bodyMap.get("username");
        String password = bodyMap.get("password");
        Authentication authentication = this.authenticate(username, password);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        return authentication;
    }

    /**
     * 更新用户最后登录时间
     *
     * @param userId 用户ID
     */
    public void updateLastLoginTimeByUserId(Long userId) {
        if (userId == null) {
            log.warn("用户ID为空，无法更新最后登录时间");
            return;
        }

        SecUser secUser = new SecUser();
        secUser.setUserId(userId);
        secUser.setLastLoginAt(new Date());

        int updated = secUserMapper.updateById(secUser);
        if (updated > 0) {
            log.info("用户 {} 最后登录时间更新成功", userId);
        } else {
            log.warn("用户 {} 最后登录时间更新失败", userId);
        }
    }

}
